package com.xzx.service;

import com.xzx.mapper.PermissionMapper;
import com.xzx.po.PermissionPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 *
 * @author xinzhixuan
 * @version 1.0
 * @date 2025/8/18 14:08
 */
@Slf4j
@Service
public class PermissionService {
    @Autowired
    private PermissionMapper permissionMapper;


    public List<PermissionPO> treeAll() {
        List<PermissionPO> list = permissionMapper.selectAll();
        Map<Long, PermissionPO> map = list.stream().collect(Collectors.toMap(PermissionPO::getId, v -> v));
        AtomicReference<Long> rootId = new AtomicReference<>(0L);
        list.forEach(permissionPO -> {
            // 防止前端ztree的组件跳转url
            permissionPO.setUrl(null);
            if (permissionPO.getPid() != 0) {
                PermissionPO parent = map.get(permissionPO.getPid());
                if (parent != null) {
                    parent.getChildren().add(permissionPO);
                }
            } else {
                rootId.set(permissionPO.getId());
            }
        });
        return Collections.singletonList(map.get(rootId.get()));
    }

    public void doAdd(PermissionPO permissionPO) {
        permissionMapper.insert(permissionPO);
    }

    public void delete(Long id) {
        permissionMapper.delete(id);
    }

    public PermissionPO getById(Long id) {
        return permissionMapper.getById(id);
    }

    public void doEdit(PermissionPO permissionPO) {
        permissionMapper.update(permissionPO);
    }

    @Transactional
    public void doAssign(Long roleId, List<Long> permissionIds) {
        permissionMapper.deleteByRoleId(roleId);
        permissionMapper.doAssign(roleId, permissionIds);
    }

    public List<PermissionPO> treeByRoleId(Long roleId) {
        Set<Long> assignPermissions = permissionMapper.selectByRoleId(roleId).stream().map(PermissionPO::getId).collect(Collectors.toSet());
        List<PermissionPO> result = treeAll();
        if (!assignPermissions.isEmpty()) {
            result.forEach(permissionPO -> {
                setChecked(permissionPO, assignPermissions);
            });
        }
        return result;
    }

    private void setChecked(PermissionPO permissionPO, Set<Long> assignPermissions) {
        permissionPO.setChecked(assignPermissions.contains(permissionPO.getId()));
        if (!permissionPO.getChildren().isEmpty()) {
            permissionPO.getChildren().forEach(child -> {
                setChecked(child, assignPermissions);
            });
        }
    }


    public void deleteByRoleIds(List<Long> roleIds) {
        permissionMapper.deleteByRoleIds(roleIds);
    }


    public List<PermissionPO> selectPermissionByUserId(Long userId) {
        return permissionMapper.selectPermissionByUserId(userId);
    }
}
